home *** CD-ROM | disk | FTP | other *** search
- /***
- *
- * Bob.h - bob definitions
- *
- * Original code: Copyright (c) 1991, by David Michael Betz. All rights reserved
- * Modifications and additions: Copyright © by Christopher E. Hyde, 1995
- *
- ***/
-
- #include "MacBob.h"
-
- // Limits
- enum {
- kLineSize = 256,
- kLineLen = kLineSize - 1,
- kLitStrLen = 250, // max literal string length
- kLitStrSize,
- kIdLen = 50, // max name/id length
- kIdSize,
- kMaxStack = 500, // runtime stack size
- kTypeNameSize = 16,
- kCodeSize = 31 * 1024, // max code size
- kMaxLoops = 10, // max level of embeded loops
- kAllocUnits = 10000 // number of allocation units per segment
- };
-
- // stack manipulation macros
- #define check(n) { if (sp - (n) < stkbase) StackOver(); }
- #define push(x,t,f) (--sp, sp->fType = (t), sp->f = (x))
- #define push_integer(x) push(x,tInteger,fInt)
- #define push_string(x) push(x,tString,fStr)
- #define push_class(x) push(x,tClass,fClass)
- #define push_object(x) push(x,tObject,fObject)
- #define push_bytecode(x) push(x,tByteCode,fVec)
- #define push_var(x) push(x,tVar,fVar)
- #define push_nil() (--sp, sp->fType = tNil)
- #define IsType(o,t) (sp[o].fType == t)
- #define IsNotType(o,t) (sp[o].fType != t)
-
- // macros to set values
- #define set(s,x,t,f) ((s)->f = (x), (s)->fType = (t))
- #define set_integer(s,x) set(s,x,tInteger,fInt)
- #define set_class(s,x) set(s,x,tClass,fClass)
- #define set_object(s,x) set(s,x,tObject,fObject)
- #define set_code(s,x) set(s,x,tCode,fCode)
- #define set_bytecode(s,x) set(s,x,tByteCode,fVec)
- #define set_dictionary(s,x) set(s,x,tDict,fDict)
- #define set_var(s,x) set(s,x,tVar,fVar)
- #define set_string(s,x) set(s,x,tString,fStr)
- #define set_vector(s,x) set(s,x,tVector,fVec)
- #define set_iostream(s,x) set(s,x,tStream,fStream)
- #define set_nil(s) ((s)->fType = tNil)
-
- // value field access macros
- #define valtype(x) ((x)->fType)
- #define isnil(x) ((x)->fType == tNil)
-
- // class field access macros
- #define claddr(x) ((x)->fClass)
- #define clgetname(x) (&claddr(x)->cl_name)
- #define clgetbase(x) (&claddr(x)->cl_base)
- #define clgetmembers(x) (&claddr(x)->cl_members)
- #define clgetfunctions(x) (&claddr(x)->cl_functions)
- #define clgetsize(x) (claddr(x)->cl_size)
-
- // object field access macros
- #define objaddr(x) ((x)->fObject)
- #define objgetclass(x) (&objaddr(x)->fClass)
- //#define objgetmember(x,i) (&objaddr(x)->fMembers[i])
- //#define objsetmember(x,i,v) (objaddr(x)->fMembers[i] = (v))
-
- // Vector field access macros
- #define vecaddr(x) ((x)->fVec)
- //#define vecgetelement(x,i) (&vecaddr(x)->fData[i])
- //#define vecsetelement(x,i,v) (vecaddr(x)->fData[i] = (v))
- #define VLen(x) ((x)->fVec->fLength)
- #define VData(x) ((x)->fVec->fData)
- #define VItem(x, i) ((x)->fVec->fData[i])
-
- // String field access macros
- #define SLen(x) ((x)->fStr->fLength)
- #define SData(x) ((x)->fStr->fData)
-
- // Dictionary field access macros
- #define digetclass(x) (&(x)->fDict->fClass)
- #define DictContents(x) ((x)->fDict->fContents)
-
- // dictionary entry field access macros
- #define deaddr(x) ((x)->fVar)
- #define degetdictionary(x) (&deaddr(x)->fDict)
- #define degetkey(x) (&deaddr(x)->fKey)
- #define degetvalue(x) (&deaddr(x)->fValue)
- #define degetnext(x) (&deaddr(x)->fNext)
- #define degettype(x) (deaddr(x)->fType)
-
- // i/o stream access macros
- #define ios_t(x) ((x)->fStream->fStream)
- #define iosclose(x) (ios_t(x)->Close())
- #define iosgetc(x) (((CIStream*) ios_t(x))->Get())
- #define iosputc(c,x) (((COStream*) ios_t(x))->Put((c)))
- #define iosputs(s,x) (((COStream*) ios_t(x))->Put((s)))
-
- #define _DefOpFn(n) void n (int argc)
-
- struct TValue;
- struct THead;
- struct TClass;
- struct TObject;
- struct TVector;
- struct TString;
- struct TDict;
- struct TEntry;
- struct TStream;
-
- typedef _DefOpFn((*OpFn)); // Built-in function prototype
-
- // Basic/low level types
- typedef int TToken;
- typedef char* Str;
- typedef const char* KStr;
- typedef char TId[kIdSize];
-
- typedef THead* Head;
- typedef TObject* Object;
- typedef TClass* Class;
- typedef TVector* Vector;
- typedef TString* String;
- typedef TDict* Dict;
- typedef TEntry* Entry;
- typedef TStream* Stream;
- typedef TValue* Value;
- typedef const TValue* ConstValue;
-
- // Value descriptor structure
- struct TValue {
- int fType; // data type
- union { // value:
- SInt32 fInt; // integer
- Class fClass; // class (in heap)
- Object fObject; // object (in heap)
- Vector fVec; // vector (in heap)
- String fStr; // string (in heap)
- Dict fDict; // dictionary (in heap)
- Entry fVar; // variable (in heap)
- OpFn fCode; // code for built-in function
- Stream fStream; // i/o stream (in heap)
- Head fHead; // (used by garbage collector)
- Value fChain; // (used by garbage collector)
- };
- };
-
- // Useful definitions
- enum {
- kValueSize = sizeof(TValue),
- kMark = 1,
- // Element indices in bytecode vector
- kIByteCodes = 0, kIClass, kIName, kIFirstLit
- };
-
- struct THead {
- char fHType;
- char fFlags;
- Value fChain;
- };
-
- struct TClass : THead {
- short cl_size;
- #if 1
- TValue cl_name;
- TValue cl_base;
- TValue cl_members;
- TValue cl_functions;
- #else
- String cl_name;
- Class cl_base;
- Dict cl_members;
- Dict cl_functions;
- #endif
- // int cl_size;
- };
-
- struct TObject : THead {
- TValue fClass;
- TValue fMembers[1];
- static inline int CalcSize (int n)
- { return sizeof(TObject) - kValueSize + n * kValueSize; }
- };
-
- struct _TVec : THead {
- int fLength;
- };
-
- struct TVector : _TVec {
- TValue fData[1];
- static inline int CalcSize (int n)
- { return sizeof(_TVec) + n * kValueSize; }
- };
-
- struct TString : _TVec {
- char fData[1];
- static inline int CalcSize (int n)
- { return sizeof(_TVec) + n; }
- };
-
- struct TDict : THead {
- TValue fClass;
- TValue fContents;
- };
-
- // Dictionary entry structure
- struct TEntry : THead {
- short fType; // symbol type
- TValue fDict; // backpointer to dictionary
- TValue fKey; // symbol name
- TValue fValue; // symbol value
- TValue fNext; // next entry
- };
-
- // I/O stream structure
- struct TStream : THead {
- CStream* fStream;
- };
-
- // Symbol types
- enum {
- _st0 = 0,
- stClass, // class definition
- stData, // data member
- stSData, // static data member
- stFunction, // function member
- stSFunction // static function member
- };
-
- // Data types
- enum {
- _tMin = 0, _tFirstMinus1 = _tMin - 1,
-
- tNil, tInteger, tCode,
- tClass, tObject, tVector, tString,
- tByteCode, tDict, tVar, tStream,
-
- _tLastPlus1, _tMax = _tLastPlus1 - 1,
- _tMarkMin = tClass, _tMarkMax = tStream
- };
-
- // Opcodes
- enum {
- _opNoOp,
- opBRT, // 01 branch on true
- opBRF, // 02 branch on false
- opBR, // 03 branch unconditionally
- opNIL, // 04 load top of stack with nil
- opPUSH, // 05 push nil onto stack
- opNOT, // 06 logical negate top of stack
- opNEG, // 07 negate top of stack
- opADD, // 08 add top two stack entries
- opSUB, // 09 subtract top two stack entries
- opMUL, // 0A multiply top two stack entries
- opDIV, // 0B divide top two stack entries
- opREM, // 0C remainder top two stack entries
- opBAND, // 0D bitwise and top two stack entries
- opBOR, // 0E bitwise or top two stack entries
- opXOR, // 0F bitwise xor top two stack entries
- opSHL, // 10 shift left top+1 stack by TOS
- opSHR, // 11 shift right top+1 stack by TOS
- opBNOT, // 12 bitwise not top of stack
- opLT, // 13 less than
- opLE, // 14 less than or equal to
- opEQ, // 15 equal to
- opNE, // 16 not equal to
- opGE, // 17 greater than or equal to
- opGT, // 18 greater than
- opINC, // 19 increment
- opDEC, // 1A decrement
- opLIT, // 1B load literal
- opRTS, // 1C return from subroutine
- opCALL, // 1D call a function
- opREF, // 1E load a variable value
- opSET, // 1F set the value of a variable
- opVREF, // 20 load a vector element
- opVSET, // 21 set a vector element
- opMREF, // 22 load a member variable value
- opMSET, // 23 set a member variable
- opAREF, // 24 load an argument value
- opASET, // 25 set an argument value
- opTREF, // 26 load a temporary variable value
- opTSET, // 27 set a temporary variable
- opTSPC, // 28 allocate temporary variable space
- opSEND, // 29 send a message to an object
- opDUP2, // 2A duplicate top two elements on the stack
- opNEW, // 2B create a new class object
- opINT, // 2C push a short int
- _opLastPlus1, _opLast = _opLastPlus1 - 1,
- _opFirst = _opNoOp + 1
- };
-
- // External variables
- extern Value stkbase, sp, fp, stktop;
- extern TValue gNil;
- extern TValue stdin_iostream, stdout_iostream, stderr_iostream;
-
- // External routines
-
- // Compiler.cp
- void InitCompiler (void);
- void MarkCompiler (void);
- void CompileDefinitions (CIStream& iStream);
-
- // Bob.cp
- void BobMain (void);
- void PrintErrF (KStr fmt, ...);
- void PrintF (KStr fmt, ...);
- void Info (KStr fmt, ...);
- void Error (KStr fmt, ...);
- void Put (KStr str);
-
- // Scanner.cp
- void InitScanner (CIStream& iStream);
- TToken Token (void);
- KStr TokenName (TToken token);
- void ParseError (KStr msg);
-
- // Interpreter.cp
- void Execute (KStr name);
- void Arg0Not (int type);
- void Arg0NotInt (void);
- void Arg1NotInt (void);
- void BadType (int off, int type);
- void StackOver (void);
-
- // Debug.cp
- void DumpProcedure (ConstValue code);
- //int DumpInstruction (ConstValue code, int lc);
- int DumpInstruction (const TVector* code, int lc);
-
- // Functions.cp
- void Print (Value ios, bool quoteIt, ConstValue val);
- void InitFunctions (void);
-
- // Memory.cp
- void Initialize (int maxStack);
- Entry AddEntry (Value dict, KStr key, int type);
- Entry FindEntry (ConstValue dict, KStr key);
- String MakeString (KStr str, int length);
- String MakeString (KStr str);
- char* GetCString (char* buf, int max, Value str);
- String NewString (int n);
- Object NewObject (Value aClass);
- Vector NewVector (int n);
- Class NewClass (KStr name, Value base);
- Dict NewDict (Value aClass);
- Stream NewIOStream (CStream& stream);
- void GC (void);
- void Mark (Value val);
-
- #pragma noreturn(Error)
- #pragma noreturn(Arg0Not)
- #pragma noreturn(Arg0NotInt)
- #pragma noreturn(Arg1NotInt)
- #pragma noreturn(BadType)
- #pragma noreturn(StackOver)
-